// f[i, j, s] 所有只摆在前i行，只摆了j个过往，并且第i行摆放的状态为s的所有方案集合
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

typedef long long LL;

const int N = 12, M = 1 << N, K = 110;

int n, m;
vector<int> state; // 合法数据
vector<int> head[M]; // //与合法状态不冲突的方案
LL dp[N][K][M];
int cnt[N]; // id存储合法状态对应的下标是多少 cnt存储数量,例如10001中1的数量为2

// 判断是否存在相邻的1
bool check(int u)
{
    for (int i = 0; i < n; i ++ )
        if ((u >> i & 1) && (u >> i + 1 & 1))
            return false;
    return true;
}

// 计算有多少个1
int count(int u)
{
    int res = 0;
    for (int i = 0; i < n; i ++ ) res += u >> i & 1;
    return res;
}

int main()
{
    cin >> n >> m; // 棋盘 国王
    //预处理出来合法的方案
    for (int i = 0; i < 1 << n; i ++ )
        if (check(i))
        {
            state.push_back(i);
            cnt[i] = count(i);
        }
    
    //预处理出来不冲突的方案
    for (auto &a : state)
        for (auto& b : state)
        {
            // int a = state[i], b = state[j];
            if ((a & b) == 0 && check(a | b))
                // 将合法方案的存储到数组中,这样可以简化状态的表示
                head[a].push_back(b);
        }
    
    dp[0][0][0] = 1;
    for (int i = 1; i <= n + 1; i ++ )
        for (int j = 0; j <= m; j ++ )
            for (auto& a : state)
                for (auto& b : head[a])
                {
                    int c = cnt[a];
                    if (j >= c)
                        dp[i][j][a] += dp[i - 1][j - c][b];
                }
    cout << dp[n + 1][m][0] << endl;
    return 0;
}